home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Tools & Apps / Networking & Communications / Serial NB Sample Driver / Task / src / printf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-15  |  12.0 KB  |  660 lines  |  [TEXT/MPS ]

  1. /************************************************************************************/
  2. /*                                                                                    */
  3. /*                printf.c - Display diagnostic/informative messages                    */
  4. /*                                                                                    */
  5. /*                Richard W. Mincher.                                5/1/87.                */
  6. /*                Philip Rakity                                    8/27/87                */
  7. /*                                                                                    */
  8. /*             Copyright © 1987-88, Apple Computer, Inc.  All rights reserved.        */
  9. /*                                                                                    */
  10. /************************************************************************************/
  11.  
  12. #include    "os.h"
  13. #include    "managers.h"
  14.  
  15.     pascal void illegal ()
  16.         extern    0x4afc;
  17.     
  18. static    char        pr_object_name [] = "print manager";
  19. static    char        pr_type_name []   = "print manager";
  20. #define    line_length    257
  21.  
  22. void
  23. printf(  string, arg )
  24. char    *string;
  25. int        arg;
  26. {
  27.     void                print_guts();
  28.     tid_type             GetPrintTID ();
  29.     static    tid_type    print_task;
  30.     long                count;
  31.     message                *msg, *m;
  32.     char                *buffer;
  33.     long                i;
  34.     unsigned    long    mid;
  35.     
  36.     for (i = 0; (print_task == 0) && (i < 30); i++)    /* Try to find a print manager */
  37.     {                
  38.         print_task = GetPrintTID ();
  39.         if (print_task == 0)
  40.             m = Receive (OS_MATCH_NONE, OS_MATCH_NONE, OS_MATCH_NONE, GetTickPS ());
  41.     }
  42.     
  43.     if (print_task == 0)
  44.         return;
  45.         
  46.     buffer = (char *)GetMem( line_length );
  47.     if (buffer)
  48.     {
  49.         msg = GetMsg();
  50.         if (msg)
  51.         {
  52.             print_guts(string, &arg, buffer);
  53.             for( count = 0; buffer[count]; count++ )
  54.                 ;
  55.                 
  56.             msg->mDataSize = count;
  57.             msg->mDataPtr = buffer;
  58.             
  59.             msg -> mTo = print_task;
  60.             
  61.             msg->mCode = PRINT_ME;
  62.             mid = msg->mId;
  63.             Send( msg );
  64.             msg = Receive( mid, OS_MATCH_ALL, OS_MATCH_ALL, 30*GetTickPS() );
  65.             if (msg != NULL)
  66.             {
  67.                 if (msg -> mCode != (PRINT_ME+1))
  68.                 {
  69.                     print_task = 0;        /* We failed to print for some reason */
  70.                 }
  71.                 FreeMem( msg->mDataPtr );
  72.                 FreeMsg( msg );
  73.             }
  74.             else
  75.             {
  76.                 print_task = 0;        /* We failed to print for some reason */
  77.             }
  78.         }
  79.         else
  80.         {
  81.             FreeMem( buffer );
  82.         }
  83.     }
  84. }
  85.  
  86. /*
  87.  *  Common code for printf et al.
  88.  *
  89.  *  The calling routine typically takes a variable number of arguments,
  90.  *  and passes the address of the first one.  This implementation
  91.  *  assumes a straightforward, stack implementation, aligned to the
  92.  *  machine's wordsize.  Increasing addresses are assumed to point to
  93.  *  successive arguments (left-to-right), as is the case for a machine
  94.  *  with a downward-growing stack with arguments pushed right-to-left.
  95.  *
  96.  *  To write, for example, fprintf() using this routine, the code
  97.  *
  98.  *    fprintf(fd, format, args)
  99.  *    FILE *fd;
  100.  *    char *format;
  101.  *    {
  102.  *    _doprnt(format, &args, fd);
  103.  *    }
  104.  *
  105.  *  would suffice.  (This example does not handle the fprintf's "return
  106.  *  value" correctly, but who looks at the return value of fprintf
  107.  *  anyway?)
  108.  *
  109.  *  This version implements the following printf features:
  110.  *
  111.  *    %d    decimal conversion
  112.  *    %u    unsigned conversion
  113.  *    %x    hexadecimal conversion
  114.  *    %X    hexadecimal conversion with capital letters
  115.  *    %o    octal conversion
  116.  *    %c    character
  117.  *    %s    string
  118.  *    %m.n    field width, precision
  119.  *    %-m.n    left adjustment
  120.  *    %0m.n    zero-padding
  121.  *    %*.*    width and precision taken from arguments
  122.  *
  123.  *  This version does not implement %f, %e, or %g.  It accepts, but
  124.  *  ignores, an `l' as in %ld, %lo, %lx, and %lu, and therefore will not
  125.  *  work correctly on machines for which sizeof(long) != sizeof(int).
  126.  *  It does not even parse %D, %O, or %U; you should be using %ld, %o and
  127.  *  %lu if you mean long conversion.
  128.  *
  129.  *  This version implements the following nonstandard features:
  130.  *
  131.  *    %b    binary conversion
  132.  *    %r    roman numeral conversion
  133.  *    %R    roman numeral conversion with capital letters
  134.  *
  135.  *  As mentioned, this version does not return any reasonable value.
  136.  *
  137.  *  Permission is granted to use, modify, or propagate this code as
  138.  *  long as this notice is incorporated.
  139.  *
  140.  *  Steve Summit 3/25/87
  141.  */
  142.  
  143. #define TRUE 1
  144. #define FALSE 0
  145.  
  146. #define ROMAN
  147.  
  148. #define isdigit(d) ((d) >= '0' && (d) <= '9')
  149. #define Ctod(c) ((c) - '0')    
  150. #define    stout(v)                             \
  151.     if(line_length > (length_of_line+=1))    \
  152.     {                                        \
  153.         *(out++) = (v);                        \
  154.     }                                        \
  155.     else                                    \
  156.     {                                        \
  157.         *(out++) = 0;                        \
  158.         return;                                \
  159.     }
  160.     
  161. #define MAXBUF (sizeof(long int) * 8)         /* enough for binary */
  162.  
  163. #ifdef ROMAN
  164. static tack();
  165. static doit();
  166. #endif
  167.  
  168. static    void
  169. print_guts(fmt, argp, out)
  170. register char *fmt;
  171. register int *argp;
  172. register char *out;
  173. {
  174. register char *p;
  175. char *p2;
  176. int size;
  177. int length;
  178. int prec;
  179. int ladjust;
  180. char padc;
  181. int n;
  182. unsigned int u;
  183. int base;
  184. char buf[MAXBUF];
  185. int negflag;
  186. char *digs;
  187. short    length_of_line;
  188. #ifdef ROMAN
  189. char *rdigs;
  190. int d;
  191. #endif
  192.  
  193. length_of_line = 0;
  194.  
  195. while(*fmt != '\0')
  196.     {
  197.     if(*fmt != '%')
  198.         {
  199.         stout(*fmt++);
  200.         continue;
  201.         }
  202.  
  203.     fmt++;
  204.  
  205.     if(*fmt == 'l')
  206.         fmt++;         /* need to use it if sizeof(int) < sizeof(long) */
  207.  
  208.     length = 0;
  209.     prec = -1;
  210.     ladjust = FALSE;
  211.     padc = ' ';
  212.  
  213.     if(*fmt == '-')
  214.         {
  215.         ladjust = TRUE;
  216.         fmt++;
  217.         }
  218.  
  219.     if(*fmt == '0')
  220.         {
  221.         padc = '0';
  222.         fmt++;
  223.         }
  224.  
  225.     if(isdigit(*fmt))
  226.         {
  227.         while(isdigit(*fmt))
  228.             length = 10 * length + Ctod(*fmt++);
  229.         }
  230.     else if(*fmt == '*')
  231.         {
  232.         length = *argp++;
  233.         fmt++;
  234.         if(length < 0)
  235.             {
  236.             ladjust = !ladjust;
  237.             length = -length;
  238.             }
  239.         }
  240.  
  241.     if(*fmt == '.')
  242.         {
  243.         fmt++;
  244.         if(isdigit(*fmt))
  245.             {
  246.             prec = 0;
  247.             while(isdigit(*fmt))
  248.                 prec = 10 * prec + Ctod(*fmt++);
  249.             }
  250.         else if(*fmt == '*')
  251.             {
  252.             prec = *argp++;
  253.             fmt++;
  254.             }
  255.         }
  256.  
  257.     negflag = FALSE;
  258.     digs = "0123456789abcdef";
  259. #ifdef ROMAN
  260.     rdigs = "  mdclxvi";
  261. #endif
  262.  
  263.     switch(*fmt)
  264.         {
  265.         case 'b':
  266.         case 'B':
  267.             u = *argp++;
  268.             base = 2;
  269.             goto donum;
  270.  
  271.         case 'c':
  272.             stout(*argp++);
  273.             break;
  274.  
  275.         case 'd':
  276.         case 'D':
  277.             n = *argp++;
  278.  
  279.             if(n >= 0)
  280.                 u = n;
  281.             else    {
  282.                 u = -n;
  283.                 negflag = TRUE;
  284.                 }
  285.  
  286.             base = 10;
  287.  
  288.             goto donum;
  289.  
  290.         case 'o':
  291.         case 'O':
  292.             u = *argp++;
  293.             base = 8;
  294.             goto donum;
  295. #ifdef ROMAN
  296.         case 'R':
  297.             rdigs = "  MDCLXVI";
  298.         case 'r':
  299.             n = *argp++;
  300.             p2 = &buf[MAXBUF - 1];
  301.  
  302.             d = n % 10;
  303.             tack(d, &rdigs[6], &p2);
  304.             n = n / 10;
  305.  
  306.             d = n % 10;
  307.             tack(d, &rdigs[4], &p2);
  308.             n = n / 10;
  309.  
  310.             d = n % 10;
  311.             tack(d, &rdigs[2], &p2);
  312.             n /= 10;
  313.  
  314.             d = n % 10;
  315.             tack(d, rdigs, &p2);
  316.  
  317.             p = p2;
  318.  
  319.             goto putpad;
  320. #endif
  321.         case 's':
  322.             p = (char *)(*argp++);
  323.  
  324.             if(p == 0)
  325.                 p = "(NIL)";
  326.  
  327.             if(length > 0 && !ladjust)
  328.                 {
  329.                 n = 0;
  330.                 p2 = p;
  331.  
  332.                 for(; *p != '\0' &&
  333.                         (prec == -1 || n < prec); p++)
  334.                     n++;
  335.  
  336.                 p = p2;
  337.  
  338.                 while(n < length)
  339.                     {
  340.                     stout(' ');
  341.                     n++;
  342.                     }
  343.                 }
  344.  
  345.             n = 0;
  346.  
  347.             while(*p != '\0')
  348.                 {
  349.                 if(++n > prec && prec != -1)
  350.                     break;
  351.  
  352.                 stout(*p++);
  353.                 }
  354.  
  355.             if(n < length && ladjust)
  356.                 {
  357.                 while(n < length)
  358.                     {
  359.                     stout(' ');
  360.                     n++;
  361.                     }
  362.                 }
  363.  
  364.             break;
  365.  
  366.         case 'u':
  367.         case 'U':
  368.             u = *argp++;
  369.             base = 10;
  370.             goto donum;
  371.  
  372.         case 'X':
  373.             digs = "0123456789ABCDEF";
  374.         case 'x':
  375.             u = *argp++;
  376.             base = 16;
  377.  
  378. donum:            p = &buf[MAXBUF - 1];
  379.  
  380.             do    {
  381.                 *p-- = digs[u % base];
  382.                 u /= base;
  383.                 } while(u != 0);
  384.  
  385.             if(negflag)
  386.                 stout('-');
  387. putpad:
  388.             size = &buf[MAXBUF - 1] - p;
  389.  
  390.             if(size < length && !ladjust)
  391.                 {
  392.                 while(length > size)
  393.                     {
  394.                     stout(padc);
  395.                     length--;
  396.                     }
  397.                 }
  398.  
  399.             while(++p != &buf[MAXBUF])
  400.                 stout(*p);
  401.  
  402.             if(size < length)    /* must be ladjust */
  403.                 {
  404.                 while(length > size)
  405.                     {
  406.                     stout(padc);
  407.                     length--;
  408.                     }
  409.                 }
  410.  
  411.             break;
  412.  
  413.         case '\0':
  414.             fmt--;
  415.             break;
  416.  
  417.         default:
  418.             stout(*fmt);
  419.         }
  420.     fmt++;
  421.     }
  422.     stout(0);
  423. }
  424.  
  425. #ifdef ROMAN
  426.  
  427. static
  428. tack(d, digs, p)
  429. int d;
  430. char *digs;
  431. char **p;
  432. {
  433. if(d == 0) return;
  434. if(d >= 1 && d <= 3)
  435.     {
  436.     doit(d, digs[2], p);
  437.     return;
  438.     }
  439.  
  440. if(d == 4 || d == 5)
  441.     {
  442.     **p = digs[1];
  443.     (*p)--;
  444.     }
  445.  
  446. if(d == 4)
  447.     {
  448.     **p = digs[2];
  449.     (*p)--;
  450.     return;
  451.     }
  452.  
  453. if(d == 5) return;
  454.  
  455. if(d >= 6 && d <= 8)
  456.     {
  457.     doit(d - 5, digs[2], p);
  458.     **p = digs[1];
  459.     (*p)--;
  460.     return;
  461.     }
  462.  
  463. /* d == 9 */
  464.  
  465. **p = digs[0];
  466. (*p)--;
  467. **p = digs[2];
  468. (*p)--;
  469. return;
  470. }
  471.  
  472. static
  473. doit(d, one, p)
  474. int d;
  475. char one;
  476. char **p;
  477. {
  478. int i;
  479.  
  480. for(i = 0; i < d; i++)
  481.     {
  482.     **p = one;
  483.     (*p)--;
  484.     }
  485. }
  486.  
  487. #endif
  488.  
  489. static tid_type GetPrintTID ()
  490. {
  491.     tid_type            printTID;
  492.     struct ra_GetCards    get_cards;
  493.     message                *msgptr;
  494.     unsigned short        index;
  495.     short                s;
  496.     
  497.     tid_type            GetIMMPrintTID();
  498.  
  499.     printTID = 0;
  500.     
  501.     if (GetICCTID () != 0)
  502.     {
  503.         if ((msgptr = GetMsg ()) == NULL)
  504.             return (printTID);
  505.     
  506.         msgptr -> mCode = ICC_GETCARDS;
  507.         msgptr -> mDataPtr = (char *) &get_cards;
  508.         msgptr -> mDataSize = sizeof (struct ra_GetCards);
  509.         msgptr -> mTo = GetICCTID ();
  510.         Send (msgptr);
  511.         
  512.         msgptr = Receive (OS_MATCH_ALL, OS_MATCH_ALL, ICC_GETCARDS+1,  OS_NO_TIMEOUT);
  513.                 
  514.         if (msgptr -> mStatus == 0)
  515.         {
  516.             for (s = 0; (s < IC_MAXCARDS) && (printTID == 0); s++)
  517.             {
  518.                 if (get_cards.tid [s] > 0)
  519.                 {
  520.                     index = 0;
  521.                     printTID = Lookup_Task (pr_object_name, pr_type_name,
  522.                                 get_cards.tid [s], &index);
  523.                 }
  524.             }
  525.         }
  526.         FreeMsg (msgptr);
  527.     }
  528.     else
  529.     {
  530.         index = 0;
  531.         printTID = Lookup_Task (pr_object_name, pr_type_name, GetNameTID (), &index);
  532.     }        
  533.  
  534.     if (printTID == 0)
  535.     {
  536.         printTID = GetIMMPrintTID();
  537.     }
  538.     
  539.     return (printTID);
  540. }
  541.  
  542. static tid_type GetIMMPrintTID ()
  543. {
  544.     tid_type            printTID;
  545.     struct ra_GetCards    get_cards;
  546.     struct ra_GetIMMs    get_imms;
  547.     message                *msgptr;
  548.     short                i;
  549.     short                immcount;
  550.     unsigned short        index;
  551.     short                s;
  552.     short                ss;
  553.     struct LookupIMMQ    LookupIMMQbuf[40];
  554.     tid_type            immTID;
  555.  
  556.     printTID = 0;
  557.     
  558.     if (GetICCTID () != 0)
  559.     {
  560.         if ((msgptr = GetMsg ()) == NULL)
  561.             return (printTID);
  562.     
  563.         msgptr -> mCode = ICC_GETIMMS;
  564.         msgptr -> mDataPtr = (char *) &get_imms;
  565.         msgptr -> mDataSize = sizeof (get_imms);
  566.         msgptr -> mTo = GetICCTID ();
  567.         Send (msgptr);
  568.         
  569.         msgptr = Receive (OS_MATCH_ALL, OS_MATCH_ALL, ICC_GETIMMS+1,  OS_NO_TIMEOUT);
  570.                 
  571.         if (msgptr -> mStatus == 0)
  572.         {
  573.             for (s = 0; (s < IC_MAXCARDS) && (printTID == 0); s++)
  574.             {
  575.                 if (get_imms.tid [s] > 0)
  576.                 {
  577.                     LookupIMMQbuf[0].objectlen  = 1;
  578.                     LookupIMMQbuf[0].object[0] = '=';
  579.                     LookupIMMQbuf[0].zonelen  = 1;
  580.                     LookupIMMQbuf[0].zone[0] = '*';
  581.                     msgptr -> mFrom = GetTID();
  582.                     msgptr -> mTo = get_imms.tid[s];
  583.                     msgptr -> mDataPtr = (char *) LookupIMMQbuf;
  584.                     msgptr -> mDataSize = sizeof (LookupIMMQbuf);
  585.                     msgptr -> mCode = IMM_LookupIMM;
  586.                     msgptr -> mOData[0] = 8;    /* retry time interval and count for NBP */
  587.                     msgptr -> mOData[1] = 1;
  588.                     Send(msgptr);
  589.                     
  590.                     msgptr = Receive (OS_MATCH_ALL, OS_MATCH_ALL, IMM_LookupIMM+1,  OS_NO_TIMEOUT);
  591.  
  592.                     immcount = msgptr -> mOData[2];
  593.                     
  594.                     for (i = 0; (i < immcount) && (printTID == 0); i++)
  595.                     {
  596.                         msgptr -> mFrom = GetTID();
  597.                         msgptr -> mTo = get_imms.tid[s];
  598.                         BlockMove(&LookupIMMQbuf[i].address[0], 
  599.                             &msgptr -> mOData[0], IM_Address_Size);
  600.                         msgptr -> mCode = IMM_MapIMM;
  601.                         Send(msgptr);
  602.                         
  603.                         msgptr = Receive (OS_MATCH_ALL, OS_MATCH_ALL, IMM_MapIMM+1,  OS_NO_TIMEOUT);
  604.                         immTID = (tid_type) msgptr -> mOData[0];
  605.                         
  606.                         msgptr -> mFrom = GetTID();
  607.                         msgptr -> mCode = ICC_GETCARDS;
  608.                         msgptr -> mDataPtr = (char *) &get_cards;
  609.                         msgptr -> mDataSize = sizeof (get_cards);
  610.                         msgptr -> mTo = immTID;
  611.                         Send (msgptr);
  612.                         
  613.                         msgptr = Receive (OS_MATCH_ALL, OS_MATCH_ALL, ICC_GETCARDS+1,  OS_NO_TIMEOUT);
  614.                                 
  615.                         if (msgptr -> mStatus == 0)
  616.                         {
  617.                             for (ss = 0; (ss < IC_MAXCARDS) && (printTID == 0); ss++)
  618.                             {
  619.                                 if (get_cards.tid [ss] > 0)
  620.                                 {
  621.                                     msgptr -> mFrom = GetTID();
  622.                                     msgptr -> mTo = get_imms.tid[s];
  623.                                     msgptr -> mOData[0] = immTID;
  624.                                     msgptr -> mOData[1] = get_cards.tid [ss];
  625.                                     msgptr -> mCode = IMM_MapTID;
  626.                                     Send(msgptr);
  627.                                     
  628.                                     msgptr = Receive (OS_MATCH_ALL, OS_MATCH_ALL, IMM_MapTID+1,  OS_NO_TIMEOUT);
  629.                                 
  630.                                     if (msgptr -> mOData[2] != 0)
  631.                                     {
  632.                                         index = 0;
  633.                                         printTID = Lookup_Task (pr_object_name, pr_type_name,
  634.                                                     msgptr -> mOData[2], &index);
  635.                                     }
  636.                                     
  637.                                     if (printTID != 0)
  638.                                     {
  639.                                         msgptr -> mFrom = GetTID();
  640.                                         msgptr -> mTo = get_imms.tid[s];
  641.                                         msgptr -> mOData[0] = msgptr -> mOData[2];
  642.                                         msgptr -> mOData[1] = printTID;
  643.                                         msgptr -> mCode = IMM_MapTID;
  644.                                         Send(msgptr);
  645.                                         
  646.                                         msgptr = Receive (OS_MATCH_ALL, OS_MATCH_ALL, IMM_MapTID+1,  OS_NO_TIMEOUT);
  647.                                         printTID = msgptr -> mOData[2];
  648.                                     }
  649.                                 }
  650.                             }
  651.                         }
  652.                     }
  653.                 }
  654.             }
  655.         }
  656.         FreeMsg (msgptr);
  657.     }
  658.     return (printTID);
  659. }
  660.